package com.tolerate.managespringboot.service.impl;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tolerate.managespringboot.Utils.TokenUtils;
import com.tolerate.managespringboot.common.Constants;
import com.tolerate.managespringboot.common.Result;
import com.tolerate.managespringboot.entity.Dto.UserDto;
import com.tolerate.managespringboot.entity.Menu;
import com.tolerate.managespringboot.entity.Role;
import com.tolerate.managespringboot.entity.RoleMenu;
import com.tolerate.managespringboot.entity.User;
import com.tolerate.managespringboot.exception.BusinessException;
import com.tolerate.managespringboot.service.MenuService;
import com.tolerate.managespringboot.service.RoleMenuService;
import com.tolerate.managespringboot.service.RoleService;
import com.tolerate.managespringboot.service.UserService;
import com.tolerate.managespringboot.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Tolerate
 * @description 针对表【sys_user】的数据库操作Service实现
 * @createDate 2024-07-02 22:17:37
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    // 注入mapper接口 调用mybatis的自己写的接口
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMenuService roleMenuService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Override
    public List<User> selectAll() {
        // 调用mapper接口的selectAll方法
        return userMapper.selectList(null);
    }

    @Override
    public Integer saveOrUpdateById(User user) {
        if (user.getId() == null) {
            // 插入
            return userMapper.insert(user);
        } else {
            // 更新
            return userMapper.updateById(user);
        }
    }

    @Override
    public List<User> pageByxml(Integer pageNum, Integer pageSize) {
        pageNum = (pageNum - 1) * pageSize;
        return userMapper.pageByxml(pageNum, pageSize);
    }

    // Mybatis ServeImpl跟新方法
    @Override
    public Boolean saveUser(User user) {
        if (user.getId() == null) {
            return this.save(user);
        } else {
            return this.updateById(user);
        }
    }

    @Override
    public Result login(User user) {
        // 重要服务，前后端都需要校验
        String username = user.getUsername();
        String password = user.getPassword();
        if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            return Result.error("用户名或密码不能为空");
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        wrapper.eq(User::getPassword, password);
        List<User> userList = this.list(wrapper);
        // 为了防止一个账号，查询出来两个数据，应该在注册账号的时候，就不让重复
        if (userList.size() == 1) {
            User userResut = userList.get(0);
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(userResut, userDto);

            // 查询用户和角色的关系，角色和菜单关联，这样就能查询出，用户和菜单的绑定关系

            // 查询出用户和角色关系
            LambdaQueryWrapper<Role> roleWrapper = new LambdaQueryWrapper<>();
            roleWrapper.eq(Role::getFlag, userResut.getRole());
            Role role = roleService.getOne(roleWrapper);

            // 查询出角色和菜单关系
            LambdaQueryWrapper<RoleMenu> roleMenuWrapper = new LambdaQueryWrapper<>();
            roleMenuWrapper.eq(RoleMenu::getRoleId, role.getId());
            List<RoleMenu> roleMenus = roleMenuService.list(roleMenuWrapper);

            // 查询出当前用户菜单信息,并且保留原来的菜单结构，父子关系
            List<Integer> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
            // 获取菜单信息
            List<Menu> menuList = (List<Menu>) menuService.getMenuTree().getData();
            // 最终返回给用户可以使用的菜单
            List<Menu> menuResult = new ArrayList<>();

            // 遍历菜单，有父亲菜单，直接将其全部加载进来，在过滤掉不存在的子集菜单
            for (Menu menu : menuList) {
                if (menuIds.contains(menu.getId())) {
                    menuResult.add(menu);
                }

                List<Menu> children = menu.getChildren();
                children.removeIf(child -> !menuIds.contains(child.getId()));
            }
            userDto.setMenus(menuResult);

            Map resultMap = new HashMap<>();
            resultMap.put("token", TokenUtils.getToken(String.valueOf(userResut.getId()), userResut.getUsername()));
            resultMap.put("user", userDto);
            return Result.success(resultMap);
        } else {
            throw new BusinessException(Constants.FAIL_500.getCode(), "用户账号/密码错误");
        }
    }
}
